<template>
    <div class="app-container">
        <el-form :inline="true" :model="query" size="mini">
            <el-form-item label="角色名称：">
                <!-- “trim()”方法被用于删除输入的字符串两端的空格↓ -->
                <el-input v-model.trim="query.name" placeholder="角色名称"></el-input>
            </el-form-item>
            <el-form-item>
                <el-button icon="el-icon-search" type="primary" @click="queryData">查询</el-button>
                <el-button icon="el-icon-refresh" @click="reload">重置</el-button>
                <el-button icon="el-icon-circle-plus-outline" type="primary" @click="openDialogAndAdd" v-if="!roleIds">新增</el-button>
                <el-button icon="el-icon-circle-plus-outline" type="success" @click="handleUserRole" v-if="roleIds">设置角色</el-button>
            </el-form-item>
        </el-form>
        <!-- “row-key”的值是一个属性名，是当前列表的唯一标识↓ -->
        <el-table ref="dataTable" :data="list" :cell-style="rowStyle" align="center" stripe border style="width: 100%" row-key="id" @selection-change="handleSelectionChange">
            <!-- 1.“type="selection"”表示“为该列添加‘多选框’”；2.“reserve-selection”仅对“type=selection”的列有效，类型为Boolean。当它的值为“true”时则会在数据更新之后保留之前选中的数据（需指定“row-key”）。因为默认情况下加上该属性后其值已自动被设置为“true”，所以无须手动绑定其值为“true”↓ -->
            <!-- “reserve-selection”必须配合上面↑的“row-key”使用，这样可以在切换页码（页面）后保留前面选中的行（选项）↓ -->
            <el-table-column type="selection" reserve-selection align="center" width="55"></el-table-column>
            <el-table-column type="index" align="center" label="序号" width="60"></el-table-column>
            <el-table-column prop="name" align="center" label="角色名称"></el-table-column>
            <el-table-column prop="remark" align="center" label="备注"></el-table-column>
            <!-- “roleIds”如果有值，则是“用户管理”模块（组件）把值传递过来了，则把操作列隐藏↓ -->
            <el-table-column align="center" v-if="!roleIds" label="操作">
            <!-- “scope”代表当前行的对象，可以通过它来获取当前行的某个属性值↓ -->
                <template slot-scope="scope">
                    <el-button type="primary" size="mini" @click="handlePermission(scope.row.id)">分配权限</el-button>
                    <el-button type="success" size="mini" @click="handleEdit(scope.row.id)">编辑</el-button>
                    <el-button type="danger" size="mini" @click="handleDelete(scope.row.id)">删除</el-button>
                </template>
            </el-table-column>
        </el-table>
        <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="page.current" :page-sizes="[10, 20, 50]" :page-size="page.size" layout="total, sizes, prev, pager, next, jumper" :total="page.total"></el-pagination>
        <edit :title="edit.title" :dialogVisible="edit.visible" :formData="edit.formData" :remoteClose="remoteClose" />
        <permission title="分配权限" :dialogVisible="permission.visible" :remoteClose="remotePermissionClose" :roleId="permission.roleId"/>
    </div>
</template>

<script>
import Edit from './edit'
import Permission from './permission'
import api from '@/api/role'
export default {
    name: 'Role', // ←注意：左边这项的值要和路由表中配置的“name”的值保持一致
    components: {Edit,Permission}, // ←注意：左边这项相当于ES5中的“Edit:Edit”
    // 当“用户管理”模块（组件）将当前这个组件文件作为子组件导入使用时，接收从父组件传递过来的属性↓
    props:{
        roleIds:null
    },
    data() {
        return {
            list:[], // ←左边这项表示“列表数据”
            page:{ // ←左边这项表示“分页对象”
                current:1, // ←左边这项表示“当前页码”
                size:20, // ←左边这项表示“每页显示的条数”
                total:0 // ←左边这项表示“总记录数”
            },
            query:{}, // ←左边这项表示“查询条件”
            edit:{ // ←注意：左边这项表示“子组件引用的属性对象”
                title:'',
                visible:false,
                formData:{}
            },
            permission:{ // ←左边这项表示“关于‘分配权限’的子组件属性”
                visible:false,
                roleId:null, // ←左边这项表示“角色ID”
            },
            checkedRoleList:[ // ←注意：左边这项被用来存储选中的角色（对象）

            ],
            
        }
    },
    created() {
        this.fetchData()
    },
    methods: {
        async fetchData(){
            const {data} = await api.getList(this.query,this.page.current,this.page.size) // ←注：左边这项采用了“解构赋值”的形式（具体为返回的“response.data”的值被赋值给了“{data}”中的“data”）
            this.list = data.records
            this.page.total = data.total
            // 列表中有数据后，勾选角色
            this.checkedRoles()
        },
        // 勾选角色
        checkedRoles(){
            // 此处注意：在<el-table>标签中一定要加上“ref="dataTable"”↓
            // 清空上一次选择的行（选项）↓
            this.$refs.dataTable.clearSelection()
            if (this.roleIds) {
                // 循环出查询到的每个角色数据，循环出来之后要判断它的ID与父组件传递的“roleIds”中的每个角色对象的ID是否匹配
                this.list.forEach(item => {
                    // indexOf()方法可返回某个指定的字符串值在字符串中首次出现的位置。如果没有找到匹配的字符串，则返回“-1”（注意：“indexOf”中“Of”的“O”一定要大写，否则浏览器会报错说“_this2.roleIds.indexof is not a function”）↓
                    // 如果匹配到了，则应该选中↓
                    if (this.roleIds.indexOf(item.id)!==-1) {
                        // 注：“true”即为“选中”。并且即使“toggleRowSelection()”的小括号中没有传递第二个参数，第二个参数的默认值也是“true”↓
                        // 选中，对应传递的是角色对象↓
                        this.$refs.dataTable.toggleRowSelection(item,true)
                    }
                })
            }
        },
        // 分配权限
        handlePermission(id){
            // 将点击的那个角色的ID传递给子组件，被用于查询该角色已经拥有的菜单IDs
            this.permission.roleId = id
            this.permission.visible = true
        },
        /* handleEdit(id){
            // console.log('编辑',id)
            // 通过ID查询详情
            api.getById(id).then(response => {
                if (response.code === 20000) {
                    // 将查询到的详情数据传递过来
                    this.edit.formData = response.data
                    this.edit.title = '编辑'
                    this.edit.visible = true
                } else {
                    
                }
            })
        }, */
        async handleEdit(id){
            // 通过ID查询详情
            const {data} = await api.getById(id) // ←注：左边这项采用了“解构赋值”的形式（具体为返回的“response.data”的值被赋值给了“{data}”中的“data”）
            this.edit.formData = data
            this.edit.title = '编辑'
            this.edit.visible = true
        },
        handleDelete(id){
            console.log('删除',id)
            this.$confirm('确认删除这条记录吗?', '提示', { // 技巧：按组合键“Shift+Tab”会让代码向左缩进
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning',
                center: true
            }).then(() => {
                // 发送删除请求
                api.deleteById(id).then(response => {
                    // 处理响应结果
                    this.$message({
                        type: response.code === 20000 ? 'success' : 'error',
                        message: response.message,
                        center:true,
                    });
                })
                // 刷新列表数据
                this.fetchData()
            }).catch(() => {
                // 点击“取消”按钮，取消删除。此处无需做任何逻辑处理（即“不用理会”，因为浏览器会自动关闭消息提示框）          
            });
        },
        // “value”表示“切换之后每页显示的条数”↓
        handleSizeChange(value){
            this.page.size = value
            this.fetchData()
        },
        // 当页码改变后触发此方法，“value”表示“当前点击或输入的（即改变后的）那个页码”↓
        handleCurrentChange(value){
            this.page.current = value
            this.fetchData()
        },
        // 条件查询
        queryData(){
            // 将页码变为“第1页”
            this.page.current = 1
            this.fetchData()
        },
        // 重置
        reload(){
            this.query = {}, // ←左边这一项表示“向‘this.query’传递空对象”
            this.fetchData()
        },
        // 打开“新增”对话框
        openDialogAndAdd(){
            this.edit.visible = true
            this.edit.title = '新增'
        },
        // 子组件会触发此事件来关闭“编辑”对话框
        remoteClose(){
            this.edit.formData = {}
            this.edit.visible = false
            this.fetchData() // ←注：如果关闭对话框后不想或无需刷新列表数据，则无需调用左边的这个方法
        },
        // 子组件会触发事件“remoteClose”来关闭“分配权限”对话框
        remotePermissionClose(){
            this.permission.visible = false
            this.permission.roleId = null
            this.fetchData() // ←注：如果关闭对话框后不想或无需刷新列表数据，则无需调用左边的这个方法
        },
        // 收集被选中的角色（“被选中的角色”会被作为参数“value”传入进来）
        handleSelectionChange(value){
            // console.log('收集被选中的角色',value)
            // “value”是由被选中的每个角色（对象）组成的数组，被选中的每个角色（对象）都会被封装到这个数组中
            this.checkedRoleList = value
        },
        // 点击“设置角色”按钮触发的方法
        handleUserRole(){
            // 存放选中的角色ID
            const checkedRoleIds = []
            // 获取每个元素（角色）中的角色ID，因为调用保存用户角色的接口，只需要选中的角色ID
            this.checkedRoleList.forEach(item => {
                // push()方法可向数组的末尾添加一个或多个元素，并返回新的长度↓
                checkedRoleIds.push(item.id)
            })
            // 触发父组件的事件函数
            this.$emit('saveUserRole',checkedRoleIds)
        },
        rowStyle(){
            return "text-align:center";
        },
    },
    watch: {
        roleIds(){
            this.query = {} // ←注：左边这一项表示“将查询条件清空”
            // 注：此处调用的是“queryData()”而非“fetchData()”（因为“queryData()”这个方法会先把页码设置为第1页，然后再调用“fetchData()”查询数据。而我们在此处就是要查询第1页的数据）↓
            this.queryData() // ←注：左边这一项表示“重新获取第1页的数据”
        }
    },
}
</script>
<style lang="scss" scoped>
    div{::v-deep.el-input__inner{text-align: center;}}
    .el-pagination , .el-select-dropdown__item {text-align: center;}
</style>